home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / LAN / NETP.ARJ / NPR.C < prev   
C/C++ Source or Header  |  1992-03-19  |  11KB  |  312 lines

  1. /*
  2.  
  3.    NetPrompt   
  4.    
  5.    Resident Module
  6.    
  7.    NPR.C
  8.    3/18/92
  9.  
  10.    F. Brett Platko
  11.  
  12.    This module contains the resident code for the TSR.
  13.    
  14. */   
  15.  
  16.  
  17. #include "cr.h"              
  18. #include "lm.h"
  19. #include "sio.h"
  20.  
  21. struct REGW regs;
  22.  
  23. char  wBuff [46] = {0};
  24.  
  25. byte  rCode;                                 // Global Return code (byte).
  26.  
  27. char  serverName   [ 48];
  28. char  volumeName   [ 16];
  29.  
  30. int   i;                                     // General Purpose counter.
  31.  
  32. word  orgPromptSize;
  33.   
  34. char  searchKey [  ] = "PROMPT=";
  35. char  localVar  [  ] = "[LOCAL] ";
  36.  
  37. char  dosEnvVar [60] = {0};
  38.  
  39. char  promptStr [48] = "$P$Q$G";
  40.  
  41. byte far *fpMasterEnv;                       // Pointer to Master Environment.
  42.  
  43. word     mEnvSize;                           // Size of Master Environment Data.
  44.  
  45. // Interrupt Service for DOS Interrupt 0x21. 
  46.  
  47. #define f_ss (dword)(_int_frame->saved_ss)   // Foreground SS register. 
  48. #define f_sp        (_int_frame->saved_sp)   // Foreground SP register. 
  49.  
  50. struct trap_rec tr = {0,                     // Trap control record.
  51.                       0,                     // Holds Old Interrupt Vector.
  52.                       0x21,                  // Interrupt Vector to be trapped.
  53.                       0,                     // Internal
  54.                       0,                     // Internal
  55.                       0,                     // Internal
  56.                       1};                    // Pass control to old interrupt if busy.
  57. void  ProcessPrompt  (void)               // Inserts the new prompt in table.
  58. {
  59.    byte  temp = 0x00;
  60.  
  61.    int freeEnv;                              // Bytes of free env space.
  62.    int promptLen;                            // Size of new prompt string.
  63.    static int n;
  64.    char termData  [2] = {0};
  65.  
  66.    word mEnvCurSize;                         // Env Size, work copy.
  67.  
  68.    byte far *fpEndEnvData;                   // Far Pointer to end of data in Env block.
  69.    byte far *fpTermData;                     // Far Pointer to 0x00 0x00 Search block. 
  70.     byte far *fpSearchKey;                    // Far Pointer to PROMPT= string. 
  71.    byte far *fpDosEnvVar;                    // Far Pointer to new prompt string.
  72.    byte far *fpTempPtr;                      // Far Work Pointer.
  73.  
  74.    byte *pTempPtr;                           // Work Pointer
  75.    
  76.    byte  curDrive;                           // Current DOS drive letter. 
  77.  
  78.    // ----------------- Get Drive Connection ID -------------------------
  79.  
  80.    curDrive = get_cur_drive();               // Get the current drive letter. 
  81.  
  82.    regs.ax  =  0xEF02;                       // GetDriveConnectionID (NetWare)
  83.  
  84.    int21 (®s, ®s);
  85.  
  86.    // The Drive connection ID table contains 32 entries of one byte each,
  87.    // 26 Letter, and 6 special. Each entry contains the connection ID 
  88.    // (1-8) of the server that is associates with that drive. A value of 
  89.    // 0 indicates that the drive is not mapped to a file server (local 
  90.    // drive or drive not used.)
  91.  
  92.    // ES:SI point to the Workstation Shell's Drive Connection ID Table.
  93.  
  94.    regs.si = regs.si + (curDrive - 0x41);       // Position offset into table.
  95.                                                 // curDir contains the ASCII letter
  96.                                                 //  so we must move it to 0 base.
  97.  
  98.    rCode = ofsg_r1(regs.si, regs.es);           // Read the byte value.
  99.    
  100.    // rCode now contains the file server number.
  101.  
  102.    if (rCode == 0x00)                           // It is a Local Drive.
  103.    {
  104.       strcpy (dosEnvVar, searchKey);
  105.       strcat (dosEnvVar, localVar);
  106.       strcat (dosEnvVar, promptStr);
  107.    }
  108.    else
  109.    {
  110.       // ---------------- Get File Server Name --------------------
  111.  
  112.       regs.ax  =  0xEF04;                       // GetFileServerName (NetWare)
  113.  
  114.       int21 (®s, ®s);
  115.  
  116.       // The File Server Name Table consists of eight entries (1-8) that are each
  117.       // 48 bytes long.  Each entry is this table can contain a null-terminated 
  118.       // server name.  
  119.  
  120.       // The first server in the File Server Table corresponds to the first entry
  121.       // in the Connection ID Table. The connection ID of a file server is the
  122.       // physical offset (1-8) that the file server occupies in these tables.
  123.  
  124.       // ES:SI points to the Shell's Server Name Table.
  125.  
  126.       regs.si = regs.si + ((rCode -1) * 48);     // Position offset into table.
  127.  
  128.       i = 0x00;
  129.  
  130.       // Copy Server Name.
  131.  
  132.       while ((temp = ofsg_r1(regs.si, regs.es)) != 0x00) // Copy server name.
  133.       { 
  134.          serverName[i] = temp;
  135.          regs.si ++;
  136.          i ++;
  137.       }
  138.  
  139.       serverName[i] = '\0';                     // Add terminating null.
  140.  
  141.       // serverName now contains the target drive's host server name.
  142.       
  143.       // ---------------- Get Drive (Volume) Handle -------------------
  144.  
  145.       regs.ax = 0xEF00;                            // GetDriveHandleTable (NetWare)
  146.  
  147.       int21 (®s, ®s);
  148.  
  149.       // The Drive Handle Table contains 32 entries of one byte each. If a drive
  150.       // has been assigned a directory handle on a file server, the directory
  151.       // handle's number appears in this table at the corresponding drive letter
  152.       // position.
  153.  
  154.       // A value of 0 indicates that the drive is not mapped to a network 
  155.       // directory.  The directory handle can be used to refer to the directory
  156.       // path mapped to the drive letter.
  157.  
  158.       // ES:SI points to the Shell's Drive Handle Table.
  159.  
  160.       regs.si = regs.si + (curDrive - 0x41);        // Position offset into table.
  161.                                                     // curDir contains the ASCII letter
  162.                                                     //  so we must move it to 0 base.
  163.  
  164.       rCode = ofsg_r1(regs.si, regs.es);            // Read the byte value.
  165.  
  166.       // rCode now contains the drive handle for the network volume.
  167.   
  168.       if (rCode != 0x00)
  169.       {
  170.          // ------------------ Get Volume Info --------------------
  171.  
  172.          // This call returns information about a volume.
  173.  
  174.          // On Entry:   AH    = E2h
  175.          //             DS:SI = Request Buffer Address
  176.          //             ES:DI = Reply Buffer Address
  177.  
  178.          // On Return:  AL    = Completion Code, 0x00 == Successful.
  179.  
  180.          regs.ax = 0xE200;             // GetVolumeInfoWithHandle.
  181.  
  182.          wBuff[0] = 0x02;              // Length of Request Buffer (-2)   
  183.          wBuff[2] = 0x15;              // Function 15 (E2/15)
  184.          wBuff[3] = rCode;             // Directory Handle of Volume.
  185.  
  186.          // Define Send Buffer Location.
  187.  
  188.          regs.ds = _cdata;             // _cdata points to TSR's Data Segment.
  189.          regs.si = wBuff;              // Offset of work buffer variable.
  190.  
  191.          // Define Reply Buffer Location.
  192.  
  193.          regs.es = _cdata;
  194.          regs.di = wBuff;  
  195.  
  196.          int21 (®s, ®s);
  197.  
  198.          // Reply Buffer:  Offset   Content              Type     Order
  199.          //                   0     Length (-2)          word     lo-hi
  200.          //                   2     Sectors Per Block    word     hi-lo
  201.          //                   4     Total Blocks         word     hi-lo
  202.          //                   6     Available Blocks     word     hi-lo
  203.          //                   8     Total Dir Slots      word     hi-lo
  204.          //                  10     Available Dir Slots  word     hi-lo
  205.          //                  12     Volume Name          byte[16]   -
  206.          //                  28     Is Volume Removable  word     hi-lo
  207.    
  208.          if ((regs.ax & 0x0000) == 0x00)  // Successful
  209.          {      
  210.             for (i = 12; i < 28; i ++)
  211.             {
  212.                volumeName[i-12] = wBuff[i];           // Copy the VolumeName.
  213.             }
  214.             
  215.             // Build Prompt string.
  216.  
  217.             strcpy (dosEnvVar, searchKey);
  218.             
  219.             strcat (dosEnvVar, "[");
  220.             strcat (dosEnvVar, serverName);
  221.             strcat (dosEnvVar, "/");
  222.             strcat (dosEnvVar, volumeName);
  223.             strcat (dosEnvVar, "] ");
  224.             strcat (dosEnvVar, promptStr);
  225.  
  226.          }
  227.       }
  228.    }  
  229.  
  230.    // ----------------  Plug New Prompt Into Env Block --------------------
  231.    
  232.    mEnvCurSize = 0x00;
  233.  
  234.    fpTermData = MK_FP (_cdata, termData);       // Create Far Pointer to Termination Code.
  235.  
  236.    fpTempPtr = fmem_find ((word) 2,             // Size of search string.
  237.                                  fpTermData,    // Search string.
  238.                                  mEnvSize,      // Size of search area.
  239.                                  fpMasterEnv);  // Where to search.
  240.  
  241.    mEnvCurSize = (word) fpTempPtr;              // Location of data termination string.
  242.  
  243.    // Since we are working with the master environment, there is no additional
  244.    // scanning required. Non-Commandline Environments would need to scan past 
  245.    // the Full Path specification that follows the environment variables.
  246.  
  247.    freeEnv = mEnvSize - mEnvCurSize;            // Calculate Free Space         
  248.    
  249.    // Now we scan for the location of the PROMPT= string. 
  250.  
  251.    fpSearchKey = MK_FP (_cdata, searchKey);     // Create far pointer to Prompt= string.
  252.  
  253.    fpTempPtr = fmem_find ((word) 7,                  
  254.                                  fpSearchKey,        
  255.                                  mEnvCurSize,        
  256.                                  fpMasterEnv);       
  257.  
  258.    if (fpTempPtr == 0x0000)                     // PROMPT is not defined so we
  259.    {                                            // will add it to the end of the env.
  260.       fpTempPtr = fpMasterEnv + mEnvCurSize + 1;
  261.       goto APPEND;
  262.    }
  263.  
  264.    orgPromptSize = fstr_len (fpTempPtr);        // Get current size of prompt string.   
  265.  
  266.    // -------- Strip out orginal prompt string from env data (PACK) -------
  267.  
  268.    n = (mEnvCurSize - (word) fpTempPtr) - orgPromptSize;       // size of packed environment.
  269.  
  270.    for (i = 0x00; i < n; i ++)
  271.    {
  272.       *fpTempPtr ++  = *((fpTempPtr + orgPromptSize) + 1);     // Relocate data.
  273.    }
  274.  
  275.    // ----------- Now append new Prompt string to env data ---------------
  276.  
  277.    APPEND:
  278.  
  279.    fpDosEnvVar = MK_FP (_cdata, dosEnvVar);     // Create far pointer to new prompt string.
  280.  
  281.    n = str_len(dosEnvVar);                      // Size of new prompt string.
  282.  
  283.    for (i = 0x00; i < n; i ++)
  284.    {
  285.       *fpTempPtr ++ = *fpDosEnvVar ++;          // Annotate Prompt string to end of env data.
  286.    } 
  287.  
  288.    *(fpTempPtr ++) = 0x00;                      // Add terminating nulls.
  289.    *(fpTempPtr ++) = 0x00;                 
  290.  
  291. }
  292.  
  293. isr21 (arg)
  294. {
  295.    static word f_ax;                      // AX value in interrupt call.
  296.    
  297.    // Get DOS 21 Function Call values.
  298.  
  299.    f_ax = ((struct glob_stk far *)((f_ss << 16) + f_sp)) -> ax; 
  300.  
  301.    if ((f_ax & 0x1900) == 0x1900)         // Function is 19 Hex (Get Default Disk Drive)
  302.    {
  303.       if (at_dos_prompt())                // If we are at the DOS prompt
  304.       {
  305.          ProcessPrompt();                 // Do new prompt.
  306.       }
  307.    }
  308.  
  309.    return(arg);                           // Pass the interrupt 21 value on.
  310. }
  311.  
  312.